<template>
  <view class="home" :style="{ paddingTop: `${menuButtonInfo.top}px` }">
    <view class="top_bar" :style="{ height: `${menuButtonInfo.height}px` }">
      <view class="back_icon" @click="back">
        <up-image :show-loading="false" src="/static/images/back.png" width="56rpx" height="56rpx"></up-image>
      </view>
      <view class="title">
        <up-image :show-loading="false" src="/static/images/ticket_title.png" width="125rpx" height="58rpx"></up-image>
      </view>
    </view>
    <view class="swiper_container" @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
      @touchcancel="handleTouchEnd">
      <view v-for="(item, index) in displayList" :key="index" class="item" :class="{
        current: index === currentIndex,
        prev: index === currentIndex - 1 || (currentIndex === 0 && displayList.length - 1 === index),
        next: index === currentIndex + 1 || (currentIndex === displayList.length - 1 && index === 0)
      }" :style="getItemStyle(index)">
        <view class="item_bar">
          <up-image :showLoading="false" width="135rpx" height="31rpx" src="/static/images/swiper_tips.png"></up-image>
          <up-image :showLoading="false" width="96rpx" height="29rpx" src="/static/images/swiper_icon.png"></up-image>
        </view>
        <view class="image">
          <up-image :showLoading="true" width="100%"
            src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2024%2F1226%2F9f773be9j00sp33gd0094d000u0010pm.jpg&thumbnail=660x2147483647&quality=80&type=jpg"
            style="aspect-ratio: 4/3;" radius="10"></up-image>
        </view>
        <view class="title">
          <up-text :text="item" color="#333333" size="15"></up-text>
        </view>
        <view class="desc flex v_center">
          <up-text text="在没有天花板和内卷的地方，不亦乐乎" color="#999999" size="13" lines="2"></up-text>
        </view>
      </view>
      <view class="indicate_bar">
        <view v-for="(item, index) in list" :key="item" class="indicate_dot"
          :class="{ active: currentIndex - 1 === index }"></view>
      </view>
    </view>
    <z-swiper grabCursor effect="cards" :modules="modules" :cardsEffect="{ slideShadows: false }">
      <z-swiper-item v-for="item in ticketList" :key="item.id">
        <view class="ticket_container" @click="buyTicket(item)">
          <view class="ticket_item">
            <view class="ticket_image"></view>
            <view class="ticket_info">
              <view class="top">
                <up-image :showLoading="false" width="96rpx" height="29rpx" src="/static/images/swiper_icon.png"
                  style="margin-bottom: 5rpx;"></up-image>
                <view class="flex h_sb">
                  <up-text text="远山见门票（单人票）" color="#2d2d2d" size="15" bold></up-text>
                  <view class="tricket_price flex v_center">
                    <text class="danwei">¥</text>
                    <text class="price_number">78</text>
                  </view>
                </view>
                <view class="text_1"></view>
              </view>
              <view class="bottom flex h_sb v_end">
                <view class="flex_d_c">
                  <view class="flex v_baseline">
                    <up-image :showLoading="false" width="16rpx" height="22rpx"
                      src="/static/images/location.png"></up-image>
                    <up-text text="泗安镇东道口村太湖梅花博览园内" size="9" color="#666666" style="margin-left: 8rpx;"></up-text>
                  </view>
                  <view class="flex v_baseline">
                    <up-image :showLoading="false" width="18rpx" height="15rpx"
                      src="/static/images/ticket.png"></up-image>
                    <up-text text="门票包含景区所有项目" size="9" color="#666666" style="margin-left: 8rpx;"></up-text>
                  </view>
                  <view class="flex v_baseline">
                    <up-image :showLoading="false" width="19rpx" height="18rpx" src="/static/images/gift.png"></up-image>
                    <up-text text="赠送 美式咖啡/果汁 一杯" size="9" color="#666666" style="margin-left: 8rpx;"></up-text>
                  </view>
                </view>
                <div class="pay_btn">
                  <up-button color="#c57f55" text="购买" shape="circle" size="mini"></up-button>
                </div>
              </view>
            </view>
          </view>
        </view>
      </z-swiper-item>
    </z-swiper>
  </view>
</template>

<script setup>
import {
  nextTick,
  onMounted,
  ref
} from 'vue';
import {
  EffectCards
} from '@/uni_modules/zebra-swiper/modules'
const modules = ref([EffectCards])
const ticketList = ref([{
  id: 1,
  name: "1"
}, {
  id: 2,
  name: "2"
}])


const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
const list = ref([1, 2, 3, 4, 5, 6])
const displayList = ref([])
const currentIndex = ref(0)
const visibleItems = ref(3)
const isResetting = ref(false); // 是否正在重置位置
const animationLock = ref(false); // 新增动画锁防止快速点击
const dragStartX = ref(0);
const dragOffset = ref(0);
const isDragging = ref(false);
const startTime = ref(0);
const dragDirectionLock = ref(null); // 方向锁（水平或垂直）

const initDisplayList = () => {
  if (!list.value.length) return
  displayList.value = [
    list.value[list.value.length - 1],
    ...list.value,
    list.value[0]
  ]
  currentIndex.value = 1
}

// 获取轮播项样式
const getItemStyle = (index) => {
  const diff = index - currentIndex.value
  const total = displayList.value.length
  const visibleItem = Math.min(visibleItems.value, total)

  // 计算缩放、位置和透明度
  let scale = 1;
  let zIndex = 1;
  let translateX = '0';
  let opacity = 1;
  // 根据索引差计算不同样式

  if (diff === 0) {
    // 当前激活项
    scale = 1;
    zIndex = visibleItem;
    opacity = 1;
  } else if (Math.abs(diff) === 1) {
    // 相邻项
    scale = 0.8
    opacity = 1
    zIndex = visibleItem - 1
    translateX = diff > 0 ? '10%' : '-10%';
  } else {
    // 其他项
    scale = 0
    opacity = 0
    zIndex = 0
    translateX = diff > 0 ? '10%' : '-10%';
  }

  // 重置状态时禁用动画
  let transition = isResetting.value ? 'none' :
    'transform 0.5s ease, opacity 0.5s ease';


  return {
    transform: `translateX(${translateX}) scale(${scale})`,
    zIndex,
    opacity,
    transition
  }
}
// 添加下一张切换方法
const next = () => {
  if (animationLock.value) return;
  animationLock.value = true;
  const total = displayList.value.length;
  const isLastItem = currentIndex.value >= total - 2;
  if (isLastItem) {
    currentIndex.value = total - 1
    setTimeout(() => {
      isResetting.value = true,
        currentIndex.value = 1;
      // 立即强制重绘; 
      nextTick(() => {
        setTimeout(() => {
          isResetting.value = false
          animationLock.value = false;
        }, 0)
      })
    }, 500)
  } else {
    currentIndex.value++
    setTimeout(() => {
      animationLock.value = false;
    }, 500);
  }
}
// 添加上一张切换方法
const prev = () => {
  if (animationLock.value) return;
  animationLock.value = true;

  const total = displayList.value.length;
  const isFirstItem = currentIndex.value <= 1;

  if (isFirstItem) {
    currentIndex.value = 0;
    setTimeout(() => {
      isResetting.value = true;
      currentIndex.value = total - 2;
      nextTick(() => {
        setTimeout(() => {
          isResetting.value = false;
          animationLock.value = false;
        }, 20);
      });
    }, 500);
  } else {
    currentIndex.value--;
    setTimeout(() => {
      animationLock.value = false;
    }, 500);
  }
};
const back = () => {
  uni.navigateBack()
}
// 在touchstart事件中记录初始位置
const handleTouchStart = (e) => {
  if (animationLock.value) return
  const touch = e.touches[0];
  dragStartX.value = touch.clientX;
  dragOffset.value = 0;
  isDragging.value = true;
  startTime.value = Date.now();
  dragDirectionLock.value = null; // 重置方向锁
}
// 在touchmove事件中处理拖动
const handleTouchMove = (e) => {
  if (!isDragging.value || animationLock.value) return;

  const touch = e.touches[0];
  const deltaX = touch.clientX - dragStartX.value;
  // const deltaY = Math.abs(touch.clientY - e.touches[0].clientY);

  // 方向锁定：首次移动超过10px时确定方向
  if (!dragDirectionLock.value && Math.abs(deltaX) > 10) {
    dragDirectionLock.value = 'horizontal';
  }

  // 只处理水平滑动
  if (dragDirectionLock.value === 'horizontal') {
    dragOffset.value = deltaX;
    e.preventDefault(); // 阻止默认滚动行为
  }
};
// 在touchend事件中处理滑动结束
const handleTouchEnd = () => {
  if (!isDragging.value || animationLock.value) return;

  isDragging.value = false;
  const endTime = Date.now();
  const duration = endTime - startTime.value;
  const deltaX = dragOffset.value;

  // 计算滑动速度 (px/ms)
  const velocity = Math.abs(deltaX) / duration;

  // 判断是否切换：距离超过50px或速度超过0.4px/ms
  if ((Math.abs(deltaX) > 50) || velocity > 0.4) {
    if (deltaX > 0) {
      prev(); // 向右滑动显示上一张
    } else {
      next(); // 向左滑动显示下一张
    }
  } else {
    // 未达到阈值则回弹到原位
    dragOffset.value = 0;
  }

  // 重置方向锁
  dragDirectionLock.value = null;
};

const buyTicket = (item) => {
  console.log(item);
}
onMounted(() => {
  initDisplayList()
})
</script>


<style lang="scss" scoped>
@import "@/uni_modules/zebra-swiper/modules/effect-creative/effect-creative.scss";

.home {
  height: 100vh;
  background-image: url('https://zxcxappimg.cxbtv.cn/qinghai/2025/07/12/18087fb30a695837776b702f03f69efb.png');
  background-position: top center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-attachment: fixed;
  box-sizing: border-box;

  .top_bar {
    position: relative;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;

    .back_icon {
      position: absolute;
      left: 40rpx;
      top: 50%;
      transform: translateY(-50%);
    }
  }

  .swiper_container {
    position: relative;
    padding: 100rpx 50rpx 0 50rpx;
    width: 100%;
    height: 820rpx;
    display: flex;
    justify-content: center;
    box-sizing: border-box;
    /* 添加3D加速提升性能 */
    transform: translate3d(0, 0, 0);
    perspective: 1000rpx;

    .item {
      position: absolute;
      width: 546rpx;
      height: 700rpx;
      border-radius: 20px;
      transform-origin: center center;
      padding: 50rpx;
      box-sizing: border-box;
      overflow: hidden;
      will-change: transform, opacity;
      transition: transform 0.5s ease, opacity 0.5s ease;
      transform-style: preserve-3d; // 启用3D变换
      backface-visibility: hidden; // 避免闪烁
    }

    .current {
      background: no-repeat top center/100% 100% url('https://zxcxappimg.cxbtv.cn/qinghai/2025/07/12/9caa38f1c03775a90acf84c1328caec2.png');
    }

    .prev {
      left: 50rpx;
      background: rgba(255, 255, 255, .4)
    }

    .next {
      right: 50rpx;
      background: rgba(255, 255, 255, .4)
    }

    .indicate_bar {
      position: absolute;
      bottom: 0;
      display: flex;
      align-items: center;
      justify-content: center;

      .indicate_dot {
        width: 10rpx;
        height: 10rpx;
        background-color: #b6bdbd;
        border-radius: 50%;
        margin: 0 3px;
      }

      .active {
        background-color: #fff;
      }
    }

    .item_bar {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .image {
      margin-top: 20rpx;
    }

    .title {
      padding: 12rpx 0;
    }

    .desc {
      text-align: center;
      height: 80rpx;
      line-height: 80rpx;
      padding: 0 25rpx;
      background-color: #efeff0;
      border-radius: 15rpx;
    }
  }

  .ticket_container {
    padding: 0 50rpx;
    margin-top: 60rpx;

    .ticket_item {
      width: 100%;
      height: 265rpx;
      background: no-repeat center/100% 100% url('/static/images/ticket_bg.png');
      padding: 15rpx 40rpx 15rpx 15rpx;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    .ticket_image {
      height: 100%;
      aspect-ratio: 9 / 14;
      border-radius: 15rpx;
      background-color: #2d2d2d;
      flex: 1;
    }

    .ticket_info {
      display: flex;
      flex-grow: 1;
      flex-direction: column;
      justify-content: space-between;
      margin-left: 50rpx;

      .tricket_price {
        align-items: baseline;
      }

      .danwei {
        font-size: 11px;
        color: #b30e1d;
      }

      .price_number {
        font-size: 20px;
        color: #ae2b2b;
        font-weight: bold;
        font-family: Bebas Neue;
      }

      .bottom {}
    }
  }

  .flex {
    display: flex;
  }

  .flex_d_c {
    flex-direction: column;
  }

  .h_sb {
    justify-content: space-between;
  }

  .v_center {
    align-items: center;
  }

  .v_end {
    align-items: flex-end;
  }

  .v_baseline {
    align-items: baseline;
  }
}
</style>
